Over its more-than-20 year history, software developers have written scores of applications in the Java object-oriented programming language. (A major implementation of Java is commercially available from Oracle Corporation of Redwood City, Calif.) Java was developed with a “write once, run anywhere” philosophy, meaning that its primary advantage is cross-platform compatibility. Accordingly, Java is designed to execute on a virtual machine, a Java Virtual Machine, or “JVM,” to be exact. While various central processing units (CPUs) host JVM implementations written specifically for them, the JVMs themselves are designed to present the same virtual computing environment to applications written in Java (“Javacode”). Java bytecode is called “bytecode.”
Nvidia Corporation of Santa Clara, Calif., has developed a Java library, called “Java on GPU,” or JoG. JoG introduces new Java classes that allow developers to accelerate the execution of Java applications on computer systems having a GPU in addition to the CPU that hosts the JVM. The GPU serves as a device relative to the host CPU. Software development tools that incorporate JoG allow automatic GPU acceleration of Java bytecode without too much special effort on the developer's part: after the JoG library is incorporated, the developer only needs to make minor changes to the Java source code to enable the automatic GPU acceleration. JoG and the tools designed to incorporate it bring to Java the remarkable processing power GPUs can provide, assuming their power is properly used.
One JoG construct is a “jog.foreach ( )” statement, which creates a jogArray object that contains necessary information and data to compile a specified class object that implements a functional interface (e.g., a lambda function) into a GPU program (which may include one or more GPU device functions). JoG source code in Table 1, below, provides an example in which lambda_mul and lambda_add are Java lambda functions that are compiled into Compute Unified Device Architecture (CUDA) programs for a GPU commercially available from Nvidia Corporation:
TABLE 1JoG Source Code ExamplejC = jog.foreach(jA, jB, lambda_mul); // statement 1jE = jog.foreach(jC, jD, lambda_add); // statement 2jE.toHost( ); // statement 3
The syntax of the jog.foreach ( ) construct is as follows:jB=jog.foreach(jA1,jA2, . . . ,jAn,lambda),where jB is a result jogArray, jA1, jA2, . . . , jAn are input jogArrays, and lambda is a class object that implements a functional interface and accepts formal arguments and captured variables as needed.
Given this syntax, the JoG source code example of Table 1 will now be explained. Statement 1 multiplies each element of jogArray jA with the corresponding element of jogArray jB and stores the product in the corresponding element of jogArray jC. (A jogArray is an array that is the subject of a GPU program.) Statement 2 then adds each element of the (newly computed) jogArray jC to the corresponding element of jogArray jD and stores the sum in the corresponding element of jogArray jE. Each jog.foreach( ) call is an invocation of a GPU program. JoG manages all data transfers between the host and the device (in both directions) as well as launching of the programs (derived from lambda_mul and lambda_add).